package be.dch.gui.panels;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public final class OutputPanel extends AbstractPanel implements ActionListener {

    /** * */
    private static final long serialVersionUID = 7762783940541751082L;
    private static final Logger LOG = Logger.getLogger(OutputPanel.class);

    private static String cmdChangeLogLevel = "LogLevelChanged";
    private static String cmdSaveLog = "saveLog";
    private static OutputPanel instance = new OutputPanel();
    private static final String COLUMN_SPECS = "1dlu,pref:grow,pref,3dlu,pref,1dlu";
    private static final String ROW_SPECS = "3dlu,pref,3dlu,300dlu,3dlu";

    private final transient JTextArea txtArea;
    private final transient JComboBox cmbLogLevel;

    private OutputPanel() {
	super();
	final FormLayout layout = new FormLayout(OutputPanel.COLUMN_SPECS, OutputPanel.ROW_SPECS);
	final CellConstraints constraints = new CellConstraints();
	final PanelBuilder builder = new PanelBuilder(layout);

	final Level[] logLevels = { Level.OFF, Level.FATAL, Level.WARN, Level.INFO, Level.DEBUG, Level.ALL };

	this.cmbLogLevel = new JComboBox(logLevels);
	this.cmbLogLevel.setActionCommand(OutputPanel.cmdChangeLogLevel);
	this.cmbLogLevel.addActionListener(this);
	this.cmbLogLevel.setSelectedItem(Logger.getRootLogger().getLevel());
	builder.add(this.cmbLogLevel, constraints.rc(2, 3));

	final JButton cmdSave = new JButton("Save");
	cmdSave.setActionCommand(OutputPanel.cmdSaveLog);
	cmdSave.addActionListener(this);
	builder.add(cmdSave, constraints.rc(2, 5));

	this.txtArea = this.createArea(null, true);
	final JScrollPane scrollPane = new JScrollPane();
	scrollPane.setViewportView(this.txtArea);
	scrollPane.setBorder(BorderFactory.createEmptyBorder());
	scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
	scrollPane.setMinimumSize(this.txtArea.getMinimumSize());
	// scrollPane.setPreferredSize(txtArea.getPreferredSize());
	// org.apache.log4j.lf5.viewer.LF5SwingUtils.makeVerticalScrollBarTrack(scrollPane);
	this.txtArea.setEditable(false);

	builder.add(scrollPane, constraints.rcw(4, 2, 4));

	this.add(builder.getPanel());
    }

    public static OutputPanel getInstance() {
	return OutputPanel.instance;
    }

    public void actionPerformed(final ActionEvent event) {
	if (event.getActionCommand() == OutputPanel.cmdChangeLogLevel) {
	    OutputPanel.LOG.log(Logger.getRootLogger().getLevel(), "Changing loglevel from " + Logger.getRootLogger().getLevel() + " to " + this.cmbLogLevel.getSelectedItem());
	    Logger.getRootLogger().setLevel((Level) this.cmbLogLevel.getSelectedItem());
	    OutputPanel.LOG.debug("Log Level changed");
	} else if (event.getActionCommand() == OutputPanel.cmdSaveLog) {
	    this.saveLogFile();
	}
    }

    @Override
    public String getPanelTitle() {
	return "Output";
    }

    @Override
    public Icon getPanelIcon() {
	return this.createImageIcon("/images/file-output-icon.jpg", "Output");
    }

    private JTextArea createArea(final String text, final boolean lineWrap) {
	final JTextArea area = new JTextArea(text);
	area.setMargin(new Insets(1, 1, 1, 1));
	area.setBackground(this.getBackground());
	area.setBorder(BorderFactory.createEmptyBorder());
	area.setLineWrap(lineWrap);
	area.setWrapStyleWord(true);
	area.setRows(35);
	area.setMinimumSize(new Dimension(650, 480));
	area.setPreferredSize(area.getMinimumSize());
	area.setMaximumSize(area.getMinimumSize());
	area.setFont(new Font("Courier New", 0, 12));
	return area;

    }

    private void saveLogFile() {

	final JFileChooser chooser = new JFileChooser();
	chooser.setDialogTitle("Saving log file");
	chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

	int result = chooser.showSaveDialog(this);
	if (result == 0) {
	    final File file = new File(chooser.getSelectedFile().getAbsolutePath());
	    if ((file != null) && file.exists()) {
		result = JOptionPane.showConfirmDialog(this, "Replace existing file?");
		if (result == JOptionPane.YES_OPTION) {
		    BufferedWriter outFile;
		    try {
			outFile = new BufferedWriter(new FileWriter(file));
			outFile.write(this.txtArea.getText()); // put in
							       // textfile
			outFile.flush(); // redundant, done by close()
			outFile.close();
		    } catch (final IOException e) {
			OutputPanel.LOG.error(e.getMessage() + ":" + e.getCause());
		    }
		}
	    }

	}

    }

    public JTextArea getTxtArea() {
	return this.txtArea;
    }

}
